﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Data;

namespace IconEditorXBAP.IconElements
{
    public class MoLine : BasicShape
    {
        private ModelicaElements.Line src;   // Modelica Line
        Polyline obj = new Polyline();  // WPF Line

        private MoLine()
            : base()
        {
            Grid.SetColumn(obj, 1);
            Grid.SetRow(obj, 1);
            obj.Stretch = Stretch.Fill;
            obj.MouseLeftButtonDown += new MouseButtonEventHandler(BasicShape_MouseLeftButtonDown);
            obj.MouseMove += new MouseEventHandler(BasicShape_MouseMove);
            obj.MouseLeftButtonUp += new MouseButtonEventHandler(BasicShape_MouseLeftButtonUp);
            obj.Margin = new Thickness(-4, -4, -4, -4);
            Panel.SetZIndex(obj, 1);

            LayoutRoot.Children.Add(obj);
        }

        public MoLine(ModelicaElements.Line _line)
            : this()
        {
            src = _line;
            LayoutRoot.DataContext = src;

            #region Bind Ellipse Dependency properties to Modelica Ellipse object

            Binding bind;   
        //public LinePattern pattern { get; set; } //= LinePattern.Solid;
        //public Arrow[] arrow { get; set; } //= new Arrow[] { Arrow.None, Arrow.None };
        //public double arrowSize { get; set; } //= 3.0;
        //public bool smooth { get; set; } //= false;

            bind = new Binding();   // visibility
            bind.Path = new PropertyPath("visible");
            bind.Converter = new VisbilityConverter();
            obj.SetBinding(Polyline.VisibilityProperty, bind);

            bind = new Binding();   // color
            bind.Path = new PropertyPath("color");
            bind.Converter = new ColorToFillConverter();
            obj.SetBinding(Polyline.StrokeProperty, bind);

            bind = new Binding();   // line thickness
            bind.Path = new PropertyPath("thickness");
            obj.SetBinding(Polyline.StrokeThicknessProperty, bind);

            //bind = new Binding();   // width
            //bind.Path = new PropertyPath("extent");
            //bind.Converter = new ExtentToWidthConverter();
            //obj.SetBinding(Polyline.WidthProperty, bind);

            //bind = new Binding();   // height
            //bind.Path = new PropertyPath("extent");
            //bind.Converter = new ExtentToHeightConverter();
            //obj.SetBinding(Polyline.HeightProperty, bind);
                        
            bind = new Binding();   // points
            bind.Path = new PropertyPath("points");
            bind.Converter = new PointsConverter();
            obj.SetBinding(Polyline.PointsProperty, bind);

            bind = new Binding();   // left
            bind.Source = src;
            bind.Path = new PropertyPath("points");
            bind.Converter = new PointsToCanvasLeftConverter();
            this.SetBinding(Canvas.LeftProperty, bind);

            bind = new Binding();   // top
            bind.Source = src;
            bind.Path = new PropertyPath("points");
            bind.Converter = new PointsToCanvasTopConverter();
            this.SetBinding(Canvas.TopProperty, bind);

            #endregion
        }

        //internal override string GetAnnotation()
        //{
        //    //Ellipse(visible=true, fillColor={255,127,127}, fillPattern=FillPattern.Solid, extent={{-35.55,-18.83},{64.45,22}}),
        //    String s = "Ellipse(visible=true, fillColor={255,127,127}, fillPattern=FillPattern.Solid, extent={{";

        //    s += Math.Round(src.extent[0, 0], 2).ToString();
        //    s += ",";
        //    s += Math.Round(src.extent[0, 1], 2).ToString();
        //    s += "},{";

        //    s += Math.Round(src.extent[1, 0], 2).ToString();
        //    s += ",";
        //    s += Math.Round(src.extent[1, 1], 2).ToString();
        //    s += "}}),";

        //    return s;
        //}

        protected override void BasicShape_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseCaptured)
            {
                // Calculate the current position of the object.
                double deltaH = e.GetPosition(null).X - mousePosition.X;
                double deltaV = e.GetPosition(null).Y - mousePosition.Y;

                for (int i = 0; i < src.points.Count; i++)
                {
                    Point p = src.points[i];
                    p.X += deltaH / 2;
                    p.Y += deltaV / 2;
                    src.points[i] = p;
                }
                // Update position global variables.
                mousePosition = e.GetPosition(null);
                src.NotifyPropertyChanged("points");
            }
        }

        protected override void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            FrameworkElement item = sender as FrameworkElement;
            switch (item.VerticalAlignment)
            {
                case System.Windows.VerticalAlignment.Bottom:  
                    // zjisti height, canvas.top a e.VerticalChange;
                    // urcit vysku a vysku bez delta
                    // urcit procento zmeny pozice kazdeho bodu
                    // kazdy bod  = top + (Y-top)*procento
                    double maxY = double.MinValue;
                    for (int i = 0; i < src.points.Count; i++)
                    {
                        if (src.points[i].Y > maxY)
                        {
                            maxY = src.points[i].Y;
                        }
                    }

                    double _top = Canvas.GetTop(this) - 100;
                    double _height = maxY - _top;
                    double diff = (_height + e.VerticalChange) / _height;

                    for (int i = 0; i < src.points.Count; i++)
                    {
                        Point p = src.points[i];
                        p.Y = _top + (p.Y - _top) * diff; ;
                        src.points[i] = p;
                    }
                    break;
                case System.Windows.VerticalAlignment.Top:
                    // zjisti height, canvas.top a e.VerticalChange;
                    // urcit vysku a vysku bez delta
                    // urcit procento zmeny pozice kazdeho bodu
                    // kazdy bod  = top + (Y-top)*procento
                    maxY = double.MinValue;
                    for (int i = 0; i < src.points.Count; i++)
                    {
                        if (src.points[i].Y > maxY)
                        {
                            maxY = src.points[i].Y;
                        }
                    }

                    _top = Canvas.GetTop(this) - 100;
                    _height = maxY - _top;
                    diff = (_height - e.VerticalChange) / _height;

                    for (int i = 0; i < src.points.Count; i++)
                    {
                        Point p = src.points[i];
                        p.Y = maxY - (maxY - p.Y) * (diff); 
                        src.points[i] = p;
                    }
                    break;
                default:
                    break;
            }

            switch (item.HorizontalAlignment)
            {
                case System.Windows.HorizontalAlignment.Left:
                    // zjisti width, canvas.left a e.HorizontalChange;
                    // urcit procento zmeny pozice kazdeho bodu
                    // kazdy bod  = left + (X-left)*procento
                    double maxX = double.MinValue;
                    for (int i = 0; i < src.points.Count; i++)
                    {
                        if (src.points[i].X > maxX)
                        {
                            maxX = src.points[i].X;
                        }
                    }

                    double _left = Canvas.GetLeft(this) - 100;
                    double _width = maxX - _left;
                    double diff = (_width - e.HorizontalChange) / _width;

                    for (int i = 0; i < src.points.Count; i++)
                    {
                        Point p = src.points[i];
                        p.X = maxX - (maxX - p.X) * diff; ;
                        src.points[i] = p;
                    }
                    break;
                case System.Windows.HorizontalAlignment.Right:
                    // zjisti width, canvas.left a e.HorizontalChange;
                    // urcit procento zmeny pozice kazdeho bodu
                    // kazdy bod  = left + (X-left)*procento
                    maxX = double.MinValue;
                    for (int i = 0; i < src.points.Count; i++)
                    {
                        if (src.points[i].X > maxX)
                        {
                            maxX = src.points[i].X;
                        }
                    }

                    _left = Canvas.GetLeft(this) - 100;
                    _width = maxX - _left;
                    diff = (_width + e.HorizontalChange) / _width;

                    for (int i = 0; i < src.points.Count; i++)
                    {
                        Point p = src.points[i];
                        p.X = _left + (p.X - _left) * diff; ;
                        src.points[i] = p;
                    }
                    break;
                default:
                    break;
            }

            e.Handled = true;
            src.NotifyPropertyChanged("points");
        }
    }
}
